#pragma once

namespace hlh
{
	template <class T>
	struct list_node
	{
		list_node* _next;
		list_node* _prev;
		T _data;

		list_node(const T& x)
			:_next(nullptr)
			,_prev(nullptr)
			,_data(x)
		{

		}
	};

	template <class T>
	struct _list_iterator
	{
		typedef list_node<T> node;
		node* _pnode;

		_list_iterator(node* p)
			:_pnode(p)
		{

		}

		// *
		T& operator*()
		{
			return _pnode->_data;
		}

		// ++
		_list_iterator<T>& operator++()
		{
			_pnode = _pnode->_next;
			return *this;
		}

		// !=
		bool operator!=(const _list_iterator<T>& it)
		{
			return _pnode != it._pnode;
		}

	};

	template <class T>
	class list
	{
		typedef list_node<T> node;
	public:
		//typedef Node* iterator;
		typedef _list_iterator<T> iterator;

		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}



		list()
		{
			_head = new node(T());
			_head->_next = _head;
			_head->_prev = _head;
		}

		void push_back(const T& x)
		{
			node* newnode = new node(x);
			node* tail = _head->_prev;

			tail->_next = newnode;
			newnode->_prev = tail;
			_head->_prev = newnode;
			newnode->_next = _head;

		}

	private:
		node* _head;
	};


	void Test_list1()
	{
		hlh::list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);

		list<int>::iterator it1 = lt1.begin();
		while (it1 != lt1.end())
		{
			cout << *it1 << " ";
			++it1;
		}
		cout << endl;
		
	}
}



